# 不使用第三方库的密度聚类

# 使用dbscan 进行密度聚类
import pandas as pd    # 读取csv 文件
import matplotlib.pyplot as plt   # 画图
import matplotlib.cm as cm
import matplotlib.colors as colors
# from sklearn.cluster import DBSCAN
# from sklearn.preprocessing import StandardScaler

# 导入手写的密度聚类
from DBscan import DBSCAN
from STandard import StandardScaler

# 0 读取csv文件

# file_path = '202412\\花洒分类\\files\\左0-2000ml-2-2024-12-10-22-43-58_point_cloud.csv'
file_path = '202412\\花洒分类\\files\\上0-800mL-2024-12-12-15-32-45_point_cloud.csv'
# file_path = '202412\\花洒分类\\files\\上0-2000mL-2024-12-12-18-58-25_point_cloud.csv'

df = pd.read_csv(file_path)
# print(df.head())

frame_index_all = list(set(df['FrameIndex']))
# print(frame_index_all)

for frame_index in frame_index_all[:20]:

    # 1 对需要的坐标进行画图
    # frame_index = 2 
    # print(df['FrameIndex'])
    frame_data = df[df['FrameIndex'] == frame_index].copy()
    # print(frame_data.shape)
    X = frame_data[[' X', '     Y']]
    SNR = frame_data[" SNR"]
    # print(frame_data)

    # 使用颜色映射
    cmap = cm.viridis
    norm = colors.Normalize(vmin=SNR.min(), vmax=SNR.max())   # 归一化 SNR 范围
    # colors = cmap(norm(SNR))

    # 绘制x,y的散点图
    plt.figure(figsize=(8, 6))
    scatter = plt.scatter(frame_data[' X'], frame_data['     Y'], c=SNR, cmap=cmap, label=f'FameIndex{frame_index}', vmin=0, vmax=30)
    plt.colorbar(scatter, label='SNR')
    # 固定坐标轴
    plt.xlim(-8, 8)
    plt.ylim(0, 8)
    # 设置图像标题和标签
    plt.title(f'Points Distribution for FrameIndex {frame_index}', fontsize=14)
    plt.xlabel('X', fontsize=12)
    plt.ylabel('Y', fontsize=12)
    plt.grid(True)
    plt.legend()
    # plt.savefig(f'202412\\花洒分类\\result_2\\左0-2000ml-2-2024-12-10-22-43-58_point_cloud_{frame_index}.png')
    # plt.savefig(f'202412\\花洒分类\\result_2\\result_0\\左0-2000ml-2-2024-12-10-22-43-58_point_cloud_{frame_index}.png')
    plt.savefig(f'E:\\data\\花洒分类\\花洒数据1月\\result\\上0-800mL-2024-12-12-15-32-45_point_cloud_{frame_index}.png')
    # plt.show()
    plt.close() 

    # 2 使用聚类算法对需要的坐标进行画图

    # 对数据进行标准化
    scaler = StandardScaler()
    # print(type(X))
    X_scaled = scaler.fit_transform(X)
    # print(type(X_scaled))
    # 使用DBSCAN进行聚类
    dbscan = DBSCAN(eps=3.6, min_samples=15)   # 调整聚类的半径 和最小阈值
    X_scaled = X_scaled.values.tolist()
    labels = dbscan.fit_predict(X_scaled)
    # print(labels)

    # 将结果加入原数据中
    frame_data['Cluster'] = labels

    # 可视化结果
    plt.figure(figsize=(8, 6))
    unique_labels = set(labels)
    # print(unique_labels)
    num_cluster = len(unique_labels)
    cmap = cm.tab10    # 使用tab10进行颜色映射
    norm = colors.Normalize(vmin=min(unique_labels), vmax=max(unique_labels))  # 归一化标签范围

    # 使用不同颜色绘制每个聚类的点
    for label in unique_labels:
        label_data = frame_data[frame_data['Cluster'] == label]
        # scatter2 = plt.scatter(label_data[' X'], label_data['     Y'], color=cmap(norm(label)), label=f'Cluster {label}')
        scatter2 = plt.scatter(label_data[' X'], label_data['     Y'], color=cmap(norm(label)), label=f'Cluster {label}')

    # 3 展示画图的结果

    # 设置图例和标题
    plt.title(f"DBSCAN Clustering Results on X, Y Coordinates, FrameIndex {frame_index}", fontsize=14)
    plt.xlabel("X", fontsize=12)
    plt.ylabel("Y", fontsize=12)
    # plt.colorbar(scatter2, label='Cluster')
    # 固定坐标轴
    plt.xlim(-8, 8)
    plt.ylim(0, 8)
    plt.legend()
    plt.grid(True)
    # plt.savefig(f'202412\\花洒分类\\result_2\\左0-2000ml-2-2024-12-10-22-43-58_point_cloud_{frame_index}_cluster.png')
    # plt.savefig(f'202412\\花洒分类\\result_2\\result_0_label\\左0-2000ml-2-2024-12-10-22-43-58_point_cloud_{frame_index}_cluster.png')
    plt.savefig(f'E:\\data\\花洒分类\\花洒数据1月\\result\\上0-800mL-2024-12-12-15-32-45_point_cloud_{frame_index}_cluster.png')
    # plt.show()
    plt.close()
    # 4 保存